package com.zl.tby.controller;

import com.zl.tby.core.base.util.*;
import com.zl.tby.core.common.R;
import com.zl.tby.icc.IccUtil;
import com.zl.tby.kafka.AnalysisUavData;
import com.zl.tby.kafka.KafkaListener;
import com.zl.tby.kafka.UavNotify;
import com.zl.tby.model.TbyEducationView;
import com.zl.tby.service.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Init;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.core.handle.MethodType;
import org.noear.solon.validation.annotation.Valid;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
 * 线程控制
 * @author changpeng
 * @version 1.0
 * @since 2024/9/27 13:30
 */
@Slf4j
@Valid
@Controller
@Mapping("/thread")
public class ThreadController {

    private ScheduledExecutorService scheduledExecutorService;

    @Inject("${kafka.url}")
    private String KAFKA_URL;
    @Inject("${kafka.topic}")
    private String TOPIC;
    @Inject("${icc.ip}")
    private String IP;
    @Inject("${icc.in-ip}")
    private String IN_IP;
    @Inject("${icc.user-name}")
    private String USER_NAME;
    @Inject("${icc.password}")
    private String PASSWORD;
    @Inject("${icc.client-id}")
    private String CLIENT_ID;
    @Inject("${icc.client-secret}")
    private String CLIENT_SECRET;
    @Inject("${geom.url}")
    private String pgJdbcUrl;
    @Inject("${geom.username}")
    private String pgUserName;
    @Inject("${geom.password}")
    private String pgPassword;
    @Inject("${mountains.url}")
    private String mountainsJdbcUrl;
    @Inject("${mountains.username}")
    private String mountainsUserName;
    @Inject("${mountains.password}")
    private String mountainsPassword;
    @Inject("${solon.env}")
    private String solonEnv;

    @Init
    public void init() {
        // 初始化大华平台的参数
        IccUtil.init(IP, IN_IP, USER_NAME, PASSWORD, CLIENT_ID, CLIENT_SECRET);
        // 图层数据库
        Pg.init(pgJdbcUrl, pgUserName, pgPassword);
        // 巡护数据库
        PgMountains.init(mountainsJdbcUrl, mountainsUserName, mountainsPassword);

        if (solonEnv.equals("demo")) {
            return;
        }

        KafkaListener.init(KAFKA_URL, TOPIC);
        //EcologySocket.start();
        scheduledExecutorService = Executors.newScheduledThreadPool(10);

        // 定时抓取车辆信息
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    ITbyCarRecordService service = Solon.context().getBean(ITbyCarRecordService.class);
                    service.grab();
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }, 10, 600, TimeUnit.SECONDS);

        // 定时抓取人脸信息
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    ITbyFaceRecordService service = Solon.context().getBean(ITbyFaceRecordService.class);
                    service.grab();
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }, 20, 1200, TimeUnit.SECONDS);

        // 一分钟执行一次，根据时间判断无人机当前的状态
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    ITbyUavKafkaService service = Solon.context().getBean(ITbyUavKafkaService.class);
                    service.checkUavStatus();
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }, 30, 60, TimeUnit.SECONDS);

        // 处理宣教馆视频截取图片线程
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    log.error("开始截取视频的图片");
                    ITbyEducationViewService service = Solon.context().getBean(ITbyEducationViewService.class);
                    service.createThumbnail(null);
                    log.error("结束截取视频的图片");
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }, 60, 300, TimeUnit.SECONDS);

        // 计算实时天气信息
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    log.error("开始计算实时天气");
                    ITbyEcologyInfoService service = Solon.context().getBean(ITbyEcologyInfoService.class);
                    service.autoCalculateRealWeather();
                    log.error("结束计算实时天气");
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }, 50, 600, TimeUnit.SECONDS);

        // 计算当天的天气信息，20分钟一次
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    String date = ToolsUtil.dateUtil2String(new Date(), "yyyy-MM-dd");
                    log.error("开始计算" + date + "天气信息");
                    ITbyEcologyInfoService service = Solon.context().getBean(ITbyEcologyInfoService.class);
                    boolean bool = service.autoCalculateDayWeather(date);
                    log.error("结束计算" + date + "天气信息");
                    if (bool) {
                        log.error("第一次计算" + date + "天气信息, 需要重新汇总昨日天气");
                        date = ToolsUtil.dateUtil2String(new Date(System.currentTimeMillis() - (1000 * 60 * 60 * 24)), "yyyy-MM-dd");
                        service.autoCalculateDayWeather(date);
                        log.error("重新汇总昨日天气结束");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }, 120, 1200, TimeUnit.SECONDS);

        // 每年一月一日将上一年的人口信息同步到本年度
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    ITbyVillagePersonService service = Solon.context().getBean(ITbyVillagePersonService.class);
                    service.autoRsyncPersonCount(true);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }, 5, 10, TimeUnit.MINUTES);

        // 试图管理生成缩略图
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    ITbyEducationViewService service = Solon.context().getBean(ITbyEducationViewService.class);
                    service.createImgThumbnail(null);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }, 60, 60, TimeUnit.SECONDS);

        // 物种头像生成缩略图
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                try {
                    ITbyAnimalPlantService service = Solon.context().getBean(ITbyAnimalPlantService.class);
                    service.createThumbnail(null);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        }, 30, 60, TimeUnit.SECONDS);
    }

    @Mapping(value = "/demo1", method = MethodType.GET)
    public R<?> demo1() throws Exception {
        ITbyVillagePersonService service = Solon.context().getBean(ITbyVillagePersonService.class);
        service.autoRsyncPersonCount(false);
        return R.ok();
    }

    @Mapping(value = "/demo", method = MethodType.GET)
    public R<UavNotify> demo() throws Exception {
        String content = "<?xml version=\"1.0\" encoding=\"gb2312\"?>\n" +
                "<Notify>\n" +
                "<CmdType>DataTransfer</CmdType>\n" +
                "<SN>1550</SN>\n" +
                "<DeviceID>10000000002000000005</DeviceID>\n" +
                "<Time>2024-11-03T10:48:02</Time>\n" +
                "<MetaVersion>v2</MetaVersion>\n" +
                "<UAV>\n" +
                "<UAVList Num=\"1\">\n" +
                "<Item>\n" +
                "</Item>\n" +
                "</UAVList>\n" +
                "</UAV>\n" +
                "</Notify>\n";
        ITbyUavKafkaService service = Solon.context().getBean(ITbyUavKafkaService.class);
        service.add(content);
        return R.ok(AnalysisUavData.analysis(content));
    }

    @Mapping(value = "/job", method = MethodType.GET)
    public R<?> job(String type, String param) {
        if (type != null && type.equals("realWeather")) {
            ITbyEcologyInfoService service = Solon.context().getBean(ITbyEcologyInfoService.class);
            service.autoCalculateRealWeather();
        } else if (type != null && type.equals("dateWeather")) {
            ITbyEcologyInfoService service = Solon.context().getBean(ITbyEcologyInfoService.class);
            service.autoCalculateDayWeather(param);
        } else if (type != null && type.equals("wrj")) {
            new Thread(() -> {
                Demo.start();
            }).start();
        } else if (type != null && type.equals("lnglat")) {
            String word = Pg.queryBj();
            System.out.println(word);
            return R.ok(word);
        }
        return R.ok();
    }

    @Mapping(value = "/wrj", method = MethodType.GET)
    public R<Void> wrj(BigDecimal lon, BigDecimal lat, Integer time) {
        new Thread(() -> {
            ITbyUavPointService pointService = Solon.context().getBean(ITbyUavPointService.class);
            ITbyUavInfoService tbyUavInfoService = Solon.context().getBean(ITbyUavInfoService.class);
            String deviceId = "10000000002000000003";
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < time.intValue(); i++) {
                BigDecimal temp = new BigDecimal(0.002).multiply(new BigDecimal(i));
                BigDecimal tempLon = ToolsUtil.add(lon, temp).setScale(6, RoundingMode.HALF_EVEN);
                BigDecimal tempLat = ToolsUtil.add(lat, temp).setScale(6, RoundingMode.HALF_EVEN);
                pointService.add(deviceId, tempLon + "," + tempLat);
                tbyUavInfoService.updateLonlat(deviceId, tempLon + "", tempLat + "");
                String suffix = i == 0 ? "" : ", ";
                builder.append(suffix + tempLon + " " + tempLat);
                try {
                    Thread.sleep(2000L);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            String point = builder.toString();
            //Pg.saveUavTrack(deviceId, new Date(System.currentTimeMillis()), point);
            System.out.println(point);
        }).start();

        /*new Thread(() -> {
            ITbyUavPointService pointService = Solon.context().getBean(ITbyUavPointService.class);
            ITbyUavInfoService tbyUavInfoService = Solon.context().getBean(ITbyUavInfoService.class);
            String deviceId = "10000000002000000001";
            StringBuilder builder = new StringBuilder();
            BigDecimal newLon = ToolsUtil.add(lon, new BigDecimal(0.005));
            for (int i = 0; i < time.intValue(); i++) {

                BigDecimal temp = new BigDecimal(0.004).multiply(new BigDecimal(i));
                BigDecimal tempLon = ToolsUtil.add(newLon, temp).setScale(6, RoundingMode.HALF_EVEN);
                BigDecimal tempLat = ToolsUtil.add(lat, temp).setScale(6, RoundingMode.HALF_EVEN);
                pointService.add(deviceId, tempLon + "," + tempLat);
                tbyUavInfoService.updateLonlat(deviceId, tempLon + "", tempLat + "");
                String suffix = i == 0 ? "" : ", ";
                builder.append(suffix + tempLon + " " + tempLat);
                try {
                    Thread.sleep(1000L);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            String point = builder.toString();
            //Pg.saveUavTrack(deviceId, new Date(System.currentTimeMillis()), point);
            System.out.println(point);
        }).start();

        new Thread(() -> {
            ITbyUavPointService pointService = Solon.context().getBean(ITbyUavPointService.class);
            ITbyUavInfoService tbyUavInfoService = Solon.context().getBean(ITbyUavInfoService.class);
            String deviceId = "10000000002000000002";
            StringBuilder builder = new StringBuilder();
            BigDecimal newLon = ToolsUtil.add(lon, new BigDecimal(0.007));
            for (int i = 0; i < time.intValue(); i++) {
                BigDecimal temp = new BigDecimal(0.006).multiply(new BigDecimal(i));
                BigDecimal tempLon = ToolsUtil.add(newLon, temp).setScale(6, RoundingMode.HALF_EVEN);
                BigDecimal tempLat = ToolsUtil.add(lat, temp).setScale(6, RoundingMode.HALF_EVEN);
                pointService.add(deviceId, tempLon + "," + tempLat);
                tbyUavInfoService.updateLonlat(deviceId, tempLon + "", tempLat + "");
                String suffix = i == 0 ? "" : ", ";
                builder.append(suffix + tempLon + " " + tempLat);
                try {
                    Thread.sleep(1000L);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            String point = builder.toString();
            //Pg.saveUavTrack(deviceId, new Date(System.currentTimeMillis()), point);
            System.out.println(point);
        }).start();*/
        return R.ok();
    }

    @Mapping(value = "/image", method = MethodType.GET)
    public R<Object> image(String type, Long id) {
        ITbyEducationViewService service = Solon.context().getBean(ITbyEducationViewService.class);
        if (type != null && type.equals("id")) {
            TbyEducationView view = service.get(id);
            String videoUrl = "http://175.44.137.60:12007" + view.getFileUrl();
            String outputPath = "/software/thumbnail/" + view.getId() + ".jpg";
            return R.ok(FFmpegFrameGrabber.captureFirstFrameLinux(videoUrl, outputPath));
        } else if (type != null && type.equals("save")) {
            service.createThumbnail(id);
        } else {
            service.createThumbnail(null);
        }
        return R.ok();
    }

    @Mapping(value = "/thumbnail", method = MethodType.GET)
    public R<?> thumbnail(Long id) {
        if (id != null) {
            ITbyEducationViewService service = Solon.context().getBean(ITbyEducationViewService.class);
            service.createImgThumbnail(id);
            return R.ok();
        }
        // 生成缩略图
        new Thread(() -> {
            ITbyEducationViewService service = Solon.context().getBean(ITbyEducationViewService.class);
            service.createImgThumbnail(null);
        }, "测试").start();
        return R.ok();
    }

    @Mapping(value = "/apThumbnail", method = MethodType.GET)
    public R<?> apThumbnail(Long id) {
        if (id != null) {
            ITbyAnimalPlantService service = Solon.context().getBean(ITbyAnimalPlantService.class);
            service.createThumbnail(id);
            return R.ok();
        }
        // 生成缩略图
        new Thread(() -> {
            ITbyAnimalPlantService service = Solon.context().getBean(ITbyAnimalPlantService.class);
            service.createThumbnail(null);
        }, "测试").start();
        return R.ok();
    }
}
